package cn.rengy.web.framework.web;

import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartRequest;

import cn.rengy.lang.ResultEntity;
import cn.rengy.web.framework.support.SpringContextHolder;
import cn.rengy.web.framework.sys.action.SysActionPO;
import cn.rengy.web.framework.sys.action.SysActionService;

import cn.hutool.core.util.ReflectUtil;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class PortalService {
	@Autowired
	private SysActionService sysActionService;
	public ResultEntity<?> portal(HttpServletRequest request,HttpServletResponse response,String action,Map<String,Object> paramMap){
		SysActionPO sysActionPO=sysActionService.getSysAction(action);
		//String className=sysActionPO.getClass_name();
		String methodName=sysActionPO.getMethod_name();
		String beanName=sysActionPO.getBean_name();
		//TODO 参数校验
		//权限校验使用拦截器实现
//		Class<?> clazz=null;
//		try {
//			clazz = Class.forName(className);
//		} catch (ClassNotFoundException e) {
//			throw new IllegalArgumentException(e.getMessage());
//		}
		Object service=SpringContextHolder.getBean(beanName);
		Method method=ReflectUtil.getMethodByName(service.getClass(), methodName);
		
		//Class<?>[] paramTypes=method.getParameterTypes();
		
		//Parameter[] parameters=method.getParameters();
		
		Object[] args=getMethodArgumentValues(method,request,response,service,methodName,paramMap);
		Object	result=ReflectUtil.invoke(service, method, args);
		if(result instanceof ResultEntity) {
			return (ResultEntity<?>)result;
		}
		return ResultEntity.ok();
	}
	
	protected Object[] getMethodArgumentValues(Method method,HttpServletRequest request,HttpServletResponse response,Object service,String methodName,Map<String,Object> paramMap) {
		
		int parameterCount=method.getParameterCount();
		Class<?>[] paramTypes=method.getParameterTypes();
		if (parameterCount==0) {
			return new Object[0];
		}

		Object[] args = new Object[parameterCount];
		for (int i = 0; i < parameterCount; i++) {
			Class<?> paramType=paramTypes[i];
			if(Map.class.isAssignableFrom(paramType)) {
				args[i]=paramMap;
			}else if (ServletRequest.class.isAssignableFrom(paramType) || MultipartRequest.class.isAssignableFrom(paramType)) {
				args[i]=request;
			}else if (HttpServletResponse.class.isAssignableFrom(paramType)) {
				args[i]=response;
			}
		}
		return args;
	}
}
